package com.smarthome.core.housemanager.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.smarthome.base.service.ShCompanyExpressService;
import com.smarthome.base.service.ShCompanyLaundryService;
import com.smarthome.base.service.ShResidenceExpressService;
import com.smarthome.base.service.ShResidenceFeeService;
import com.smarthome.base.service.ShResidenceLaundryService;
import com.smarthome.base.service.ShResidenceService;
import com.smarthome.base.service.ShUserRoleService;
import com.smarthome.common.tools.ApiCachedKeysUtil;
import com.smarthome.common.tools.SHACipher;
import com.smarthome.common.tools.cache.JedisUtils;
import com.smarthome.core.account.AccountDoorService;
import com.smarthome.core.housemanager.ResidenceManagerService;
import com.smarthome.domain.bean.ShAccount;
import com.smarthome.domain.bean.ShAccountDoor;
import com.smarthome.domain.bean.ShCompanyExpress;
import com.smarthome.domain.bean.ShCompanyLaundry;
import com.smarthome.domain.bean.ShResidence;
import com.smarthome.domain.bean.ShResidenceExpress;
import com.smarthome.domain.bean.ShResidenceFee;
import com.smarthome.domain.bean.ShResidenceLaundry;
import com.smarthome.domain.bean.ShUserRole;
import com.smarthome.domain.vo.boss.Combobox;
import com.smarthome.domain.vo.boss.DataGrid;
import com.smarthome.domain.vo.boss.PageHelper;
import com.smarthome.domain.vo.boss.Tree;

@Service("residenceManagerService")
public class ResidenceManagerServiceImpl implements ResidenceManagerService {

    @Resource(name = "shResidenceService")
    private ShResidenceService shResidenceService;

    @Resource(name = "shUserRoleService")
    private ShUserRoleService userRoleService;

    @Resource(name = "shResidenceFeeService")
    private ShResidenceFeeService rsidenceFeeService;
    
    @Resource
    private AccountDoorService accountDoorService;
    
    @Resource
    private ShCompanyExpressService shCompanyExpressService;
    
    @Resource
    private ShCompanyLaundryService shCompanyLaundryService;
    
    @Resource
    private ShResidenceExpressService shResidenceExpressService;
    
    @Resource
    private ShResidenceLaundryService shResidenceLaundryService;
    
    @Override
    public List<ShResidence> addOtherParam(List<ShResidence> residences) {
        if (null == residences || residences.size() == 0)
            return residences;
        // 获取小区ids
        Long[] ids = new Long[residences.size()];
        for (int i = 0; i < residences.size(); i++) {
            ids[i] = residences.get(i).getId();
        }
        // 资源角色名称
        List<ShUserRole> userRoles = userRoleService.queryUserRoleRootByResidenceId(ids);
        List<ShResidenceFee> fees = rsidenceFeeService.selectEntryLisByResidenceId(ids);
        // 物业公司
        Map<Long, ShUserRole> roleMap = new HashMap<Long, ShUserRole>();
        // 物业费
        Map<Long, ShResidenceFee> feeMap = new HashMap<Long, ShResidenceFee>();
        if (null != userRoles) {
            for (ShUserRole role : userRoles) {
                roleMap.put(role.getResidenceId(), role);
            }
        }
        if (null != fees) {
            for (ShResidenceFee fee : fees) {
                feeMap.put(fee.getResidenceId(), fee);
            }
        }

        for (ShResidence residence : residences) {
            residence.setResidenceFee(feeMap.get(residence.getId()));
            residence.setUserRole(roleMap.get(residence.getId()));
        }

        return residences;
    }

    @Override
    public DataGrid getDataGrid(ShResidence residence, PageHelper helper) {
        // TODO Auto-generated method stub
        DataGrid grid = shResidenceService.queryDataGrid(residence, helper);
        // addOtherParam
        if (null != grid && null != grid.getRows()) {
            grid.setRows(addOtherParam(grid.getRows()));
        }
        return grid;
    }

    @Override
    public int add(ShResidence residence) {
        // TODO Auto-generated method stub
        return shResidenceService.insert(residence);
    }

    @Override
    public int edit(ShResidence residence) {
        ShResidence shResidence = shResidenceService.selectEntryById(residence.getId());
        if (shResidence != null) {
            BeanUtils.copyProperties(residence, shResidence);
            return shResidenceService.saveOrUpdate(shResidence);
        }
        return 0;
    }

    @Override
    public int delte(Long id) {

        return shResidenceService.deleteByIds(id);
    }

    @Override
    public ShResidence queryResidenceById(Long id) {
        return shResidenceService.selectEntryById(id);
    }

    @Override
    public List<ShResidence> queryShResidences(ShResidence residence) {
        return shResidenceService.selectEntryList(residence);
    }

    @Override
    public List<Tree> getTree() {
        List<ShResidence> res = shResidenceService.selectEntryList(null);
        List<Tree> trees = new ArrayList<Tree>();
        if (res != null) {
            for (ShResidence r : res) {
                Tree t = new Tree();
                t.setId(r.getId());
                t.setText(r.getName());
                t.setAttributes(r);
                trees.add(t);
            }
        }
        return trees;
    }

    @Override
    public List<Combobox> getCombobox() {
        List<ShResidence> res = shResidenceService.selectEntryList(null);
        List<Combobox> result = new ArrayList<Combobox>();
        for (ShResidence sr : res) {
            Combobox combo = new Combobox(sr.getId() + "", sr.getName());
            result.add(combo);
        }
        return result;
    }

    @Override
    public List<ShResidence> queryResidencesByUserId(Long userId) {
        return shResidenceService.queryResidencesByUserId(userId);
    }

    @Override
    public void resetResidenceForAccount(ShAccount account) {
        List<ShResidence> shResidences = shResidenceService.queryResidencesByAccountId(account.getId());
        if (null == shResidences || shResidences.size() == 0) {
            shResidences = new ArrayList<ShResidence>();
            ShResidence shResidence = new ShResidence();
            shResidence.setId(0L);
            shResidence.setName("未设置小区");
            shResidences.add(shResidence);
        }
        account.setResidenceId(shResidences.get(0).getId());
        account.setResidenceName(shResidences.get(0).getName());
        account.setResidences(shResidences);
        
        ShAccountDoor accountDoor = accountDoorService.getDefaultDoor(account.getId(), account.getResidenceId());
        if(accountDoor != null){
            account.setDoorId(accountDoor.getDoorId());
            account.setDoorName(accountDoor.getDoorName());
        }
        try {
            String token = SHACipher.encrypt(account.getMobile());
            JedisUtils.set(ApiCachedKeysUtil.getKey(ApiCachedKeysUtil.MODULE_MOBILE_TOKEN, token), account);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void changeCurrentResidenceForAccount(ShAccount account, Long residenceId) {
        List<ShResidence> shResidences = shResidenceService.queryResidencesByAccountId(account.getId());
        for (ShResidence residence : shResidences) {
            if (residence.getId().equals(residenceId)) {
                account.setResidenceId(residence.getId());
                account.setResidenceName(residence.getName());
                break;
            }
        }
        try {
        	ShAccountDoor accountDoor = accountDoorService.getDefaultDoor(account.getId(), account.getResidenceId());
            if(accountDoor != null){
                account.setDoorId(accountDoor.getDoorId());
                account.setDoorName(accountDoor.getDoorName());
            }
            String token = SHACipher.encrypt(account.getMobile());
            JedisUtils.set(ApiCachedKeysUtil.getKey(ApiCachedKeysUtil.MODULE_MOBILE_TOKEN, token), account);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

	@Override
	public List<Tree> getCompanyExpressByResidence(ShResidence residence) {
		ShCompanyExpress queryExpress = new ShCompanyExpress();
		queryExpress.setAreaId(residence.getAreaId());
		queryExpress.setStatus(1);
		queryExpress.setOrderField("sortWeight");
		queryExpress.setOrderFieldType("desc");
		Tree root = shCompanyExpressService.getTree(queryExpress);
		List<Tree> treeList = root.getChildren();
		int length = treeList.size();
		ShResidenceExpress queryResidenceExpress = new ShResidenceExpress();
		queryResidenceExpress.setResidenceId(residence.getId());
		List<Long> expressIdList = shResidenceExpressService.getExpressIdList(queryResidenceExpress);
		
		if(expressIdList != null) {
			for(int i = 0;i < length;i++) {
				if(expressIdList.contains(treeList.get(i).getId())) {
					treeList.get(i).setChecked(true);
				}
			}
		}
 		
		List<Tree> result = new ArrayList<Tree>();
		result.add(root);
		return result;
	}

	@Override
	public void saveResidenceExpress(String expressIds, Long residenceId) {
		String[] expressIdsArr = expressIds.split(",");
		List<String> newExpressIdList = Arrays.asList(expressIdsArr);
		ShResidenceExpress queryResidenceExpress = new ShResidenceExpress();
		queryResidenceExpress.setResidenceId(residenceId);
		List<Long> oldExpressIdList = shResidenceExpressService.getExpressIdList(queryResidenceExpress);
		List<ShResidenceExpress> oldResidenceExpressList = shResidenceExpressService.selectEntryList(queryResidenceExpress);
		int length = 0;
		if(oldResidenceExpressList != null) {
			length = oldResidenceExpressList.size();
			List<Long> ids = new ArrayList<Long>();
			for(int i = 0;i < length;i++) {
				if(!newExpressIdList.contains(oldResidenceExpressList.get(i).getExpressId().toString())) {
					ids.add(oldResidenceExpressList.get(i).getId());
				}
			}
			if(ids.size() != 0) {
				try {
					shResidenceExpressService.deleteByIds(ids.toArray(new Long[ids.size()]));
				}catch(Exception e) {
					throw e;
				}
			}
		}
		
		if(newExpressIdList != null) {
			length = newExpressIdList.size();
			List<ShResidenceExpress> residenceExpresses = new ArrayList<ShResidenceExpress>();
			for(int i = 0;i < length;i++) {
				if((oldExpressIdList == null || !oldExpressIdList.contains(Long.parseLong(newExpressIdList.get(i)))) && !newExpressIdList.get(i).equals("0")) {
					residenceExpresses.add(new ShResidenceExpress(residenceId,Long.parseLong(newExpressIdList.get(i))));
				}
			}
			if(residenceExpresses.size() != 0) {
				try{
					shResidenceExpressService.insert(residenceExpresses.toArray(new ShResidenceExpress[residenceExpresses.size()]));
				}catch(Exception e) {
					throw e;
				}
			}
		}
		
	}

	@Override
	public List<Tree> getCompanyLaundryByResidence(ShResidence residence) {
		ShCompanyLaundry queryLaundry = new ShCompanyLaundry();
		queryLaundry.setAreaId(residence.getAreaId());
		queryLaundry.setStatus(1);
		queryLaundry.setOrderField("sortWeight");
		queryLaundry.setOrderFieldType("desc");
		Tree root = shCompanyLaundryService.getTree(queryLaundry);
		List<Tree> treeList = root.getChildren();
		int length = treeList.size();
		ShResidenceLaundry queryResidenceLaundry = new ShResidenceLaundry();
		queryResidenceLaundry.setResidenceId(residence.getId());
		List<Long> LaundryIdList = shResidenceLaundryService.getLaundryIdList(queryResidenceLaundry);
		
		if(LaundryIdList != null) {
			for(int i = 0;i < length;i++) {
				if(LaundryIdList.contains(treeList.get(i).getId())) {
					treeList.get(i).setChecked(true);
				}
			}
		}
 		
		List<Tree> result = new ArrayList<Tree>();
		result.add(root);
		return result;
	}

	@Override
	public void saveResidenceLaundry(String laundryIds, Long residenceId) {
		String[] laundryIdsArr = laundryIds.split(",");
		List<String> newLaundryIdList = Arrays.asList(laundryIdsArr);
		ShResidenceLaundry queryResidenceLaundry = new ShResidenceLaundry();
		queryResidenceLaundry.setResidenceId(residenceId);
		List<Long> oldLaundryIdList = shResidenceLaundryService.getLaundryIdList(queryResidenceLaundry);
		List<ShResidenceLaundry> oldResidenceLaundryList = shResidenceLaundryService.selectEntryList(queryResidenceLaundry);
		int length = 0;
		if(oldResidenceLaundryList != null) {
			length = oldResidenceLaundryList.size();
			List<Long> ids = new ArrayList<Long>();
			for(int i = 0;i < length;i++) {
				if(!newLaundryIdList.contains(oldResidenceLaundryList.get(i).getLaundryId().toString())) {
					ids.add(oldResidenceLaundryList.get(i).getId());
				}
			}
			if(ids.size() != 0) {
				try {
					shResidenceLaundryService.deleteByIds(ids.toArray(new Long[ids.size()]));
				}catch(Exception e) {
					throw e;
				}
			}
		}
		
		if(newLaundryIdList != null) {
			length = newLaundryIdList.size();
			List<ShResidenceLaundry> residenceLaundrys = new ArrayList<ShResidenceLaundry>();
			for(int i = 0;i < length;i++) {
				if((oldLaundryIdList == null || !oldLaundryIdList.contains(Long.parseLong(newLaundryIdList.get(i)))) && !newLaundryIdList.get(i).equals("0")) {
					residenceLaundrys.add(new ShResidenceLaundry(residenceId,Long.parseLong(newLaundryIdList.get(i))));
				}
			}
			if(residenceLaundrys.size() != 0) {
				try{
					shResidenceLaundryService.insert(residenceLaundrys.toArray(new ShResidenceLaundry[residenceLaundrys.size()]));
				}catch(Exception e) {
					throw e;
				}
			}
		}
	}
}
